#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#include "app_main.h"
#include "app_beep.h"

typedef enum
{
    MATCH_OVER = 0,
    MATCH_START_PLAY,
    MATCH_LEARN_START_PLAY,
    MATCH_LEARN_START,
    MATCH_LEARN_SUCCESS_PLAY,
    MATCH_LEARN_FAILURE_PLAY,
    MATCH_LEARN_SUCCESS,
    MATCH_LEARN_FAILURE,
    MATCH_SUCCESS_PLAY,
    MATCH_FAILURE_PLAY,
    MATCH_SUCCESS,
    MATCH_FAILURE,
    MATCH_NEXT_ONE_SUCCESS_PLYA,
    MATCH_NEXT_ONE_FAILURE_PLYA,
} MATCH_REMOTE_FLAG;

volatile unsigned char f_asr_response = -1;
extern unsigned char *remote_ptr_data;
extern REMOTE_PARA_T remote_data;
extern AIR_STA_T air_sta_data;

#define LOG_TEST

#define DATA_FLASH_KEY "2021-01-14"

unsigned char match_remote_flag = 0;

static void air_user_data_init()
{
    int ret = 0;
    unsigned short info[5] = {0};
    unsigned char wind_direct_flag = 0;
    unsigned char wind = 0;
    int i = 0;
    int j = 0;

    ret = read_remote_code(IR_DEV_AIR_COND);
    if (ret == -1)
    {
        printf("\nFail to read data, error code = %d!\n", ret);
        return;
    }
    else
    {
        ret = get_ac_info(remote_ptr_data, remote_data._len, info, &wind_direct_flag);
        free_remote_code();
        if (ret < 0)
        {
            printf("\nGet info error!!!\n");
            return;
        }
    }

#ifdef LOG_TEST
    printf("\nGet data:\nwind_direct_flag %d;", wind_direct_flag);
#endif
    for (i = 0; i < 5; i++)
    {
        printf("%02X;", info[i]);
    }

    for (i = 0; i < 5; i++)
    {
        if (info[i] != 0)
        {
            air_sta_data._mode = i;
            break;
        }
    }

    air_sta_data._temperature = (info[i] & 0x0F) + 16;
    wind = (info[i] >> 8) & 0x0F;
    for (; j < 4; j++)
    {
        if ((wind & 0x01) == 1)
        {
            air_sta_data._wind_speed = j;
            break;
        }
        wind = wind >> 1;
    }

    air_sta_data._power = 1;
    air_sta_data._wind_direction = 1;
    air_sta_data._frequency = 38000;
    air_sta_data._sync = 0;

#ifdef LOG_TEST
    printf("\nInit_user_air_dat: _power=%d, _mode=%d, _temperature=%d, _wind_speed=%d, _wind_direction=%d\n",
           air_sta_data._power, air_sta_data._mode, air_sta_data._temperature, air_sta_data._wind_speed, air_sta_data._wind_direction);
#endif
}

/**
 * @brief 初始化遥控器参数，需要在其他所有初始化完成后再调用该函数
 * @return 0: OK    -1:读取flash遥控器参数失败  -3：获取遥控器数据失败 -4 ：获取遥控器控制码失败
 */
void remote_data_init()
{
    int ret = 0;
    AIR_STA_T temp_user_air_data;

    // printf(LOG_TAG);
    ret = app_extflash_read(SPI_FLASH_REMOTE_ADDR, &remote_data, sizeof(remote_data));
    if (ret < 0)
    {
        printf("\nFail to read air remote data, error code = %d!\n", ret);
    }
    else
    {
        printf("\nRead_flash_air_remote: ret=%d, remote_num=%d, remote_handle=%d, remote_id=%d, remote_data_offset=%d, remote_data_len=%d, remote_cur_num=%d, remote_flag=%d\n",
               ret, remote_data._num, remote_data._handle, remote_data._id, remote_data._offset, remote_data._len, remote_data._cur_num, remote_data._flag);
        printf("remote key :%s\n", remote_data.key);

        if (!memcmp((char *)remote_data.key, (char *)DATA_FLASH_KEY, 10))
        {
            ret = app_extflash_read(SPI_FLASH_USER_AIR_DATA_ADDR, &temp_user_air_data, sizeof(temp_user_air_data));
            if (ret < 0)
            {
                printf("Fail to read air user data, error code = %d!\n", ret);
            }
            else
            {
                printf("user air key :%s\n", temp_user_air_data.key);
                if (!strcmp((char *)temp_user_air_data.key, (char *)DATA_FLASH_KEY))
                {
                    air_sta_data = temp_user_air_data;
                    printf("Read air uasr data success..\n");
                }
                else
                {
                    air_user_data_init();
                    printf("Initializes air user data..\n");
                }

                printf("Read_flash_user_air_dat: _power=%d, _mode=%d, _temperature=%d, _wind_speed=%d, _wind_direction=%d\n",
                       air_sta_data._power, air_sta_data._mode, air_sta_data._temperature, air_sta_data._wind_speed, air_sta_data._wind_direction);
            }
        }
        else
        {
            memset(&remote_data, 0, sizeof(remote_data));
            printf("Please match the remote control first\n");
        }
    }

    // printf(LOG_TAG);

    return;
}

/**
 * @brief 匹配空调遥控器
 * @return 0: OK    -1:error
 */
int match_remote_process(void)
{
    if (match_remote_flag == 0)
    {
        return -1;
    }
    int ret = 0;
    static unsigned char step = MATCH_START_PLAY;
    switch (step)
    {
    case MATCH_START_PLAY:
        //匹配开始
        f_asr_response = BEEP_0006;
        step = MATCH_LEARN_START_PLAY;
        // printf(LOG_TAG);
#ifdef LOG_TEST
        printf("\nPLAY:match remote start ..\n");
#endif
        break;

    case MATCH_LEARN_START_PLAY:
        //请按空条遥控器电源键
        f_asr_response = BEEP_0005;
        step = MATCH_LEARN_START;
#ifdef LOG_TEST
        printf("\nPLAY:please press the power button of the air conditioning remote control ..\n");
#endif
        break;

    case MATCH_LEARN_START:
        ret = learn_pulse_start();
        if (ret != 0)
        {
            printf("\nLearn remote failure ..\n");
            step = MATCH_FAILURE_PLAY;
            return -1;
        }
        else
        {
            step = MATCH_LEARN_SUCCESS;
#ifdef LOG_TEST
            printf("\nLearn remote suucess ..\n");
#endif
        }
        break;

    case MATCH_LEARN_SUCCESS:
        ret = match_remote_start(IR_DEV_AIR_COND);
        if (ret != 0)
        {
            printf("\nSearch_remote return error:ret=%d\n", ret);
            step = MATCH_FAILURE_PLAY;
            return -1;
        }
        step = MATCH_SUCCESS_PLAY;
#ifdef LOG_TEST
        printf("\nMatch remote success ..\n");
#endif
        break;

    case MATCH_SUCCESS_PLAY:
        //匹配成功
        f_asr_response = BEEP_0007;
        step = MATCH_SUCCESS;
#ifdef LOG_TEST
        printf("\nPLAY:match remote success ..\n");
#endif
        break;

    case MATCH_FAILURE_PLAY:
        //匹配失败
        f_asr_response = BEEP_0008;
        step = MATCH_FAILURE;
#ifdef LOG_TEST
        printf("\nPLAY:match remote error ..\n");
#endif
        break;

    case MATCH_SUCCESS:

        step = MATCH_OVER;
        air_user_data_init();
        save_user_sta_data(&air_sta_data, sizeof(air_sta_data), IR_DEV_AIR_COND);
        break;

    case MATCH_FAILURE:
        ret = match_get_next_remote(IR_DEV_AIR_COND);
        if (ret < 0)
        {
            step = MATCH_NEXT_ONE_FAILURE_PLYA;
            printf("\nNo available data was detected!!!\n");
        }
        else
        {
            step = MATCH_NEXT_ONE_SUCCESS_PLYA;
            air_user_data_init();
            save_user_sta_data(&air_sta_data, sizeof(air_sta_data), IR_DEV_AIR_COND);
#ifdef LOG_TEST
            printf("\nSuccessfully obtained the next set of remote control codes...\n");
#endif
        }
        break;

    case MATCH_NEXT_ONE_SUCCESS_PLYA:
        f_asr_response = BEEP_0119;
        step = MATCH_OVER;
#ifdef LOG_TEST
        printf("\nPLAY:Successfully obtained the next set of remote control codes...\n");
#endif
        break;

    case MATCH_NEXT_ONE_FAILURE_PLYA:
        f_asr_response = BEEP_0120;
        step = MATCH_OVER;
#ifdef LOG_TEST
        printf("\nPLAY:No available data was detected!!!\n");
#endif
        break;

    case MATCH_OVER:
        //匹配结束
        match_remote_flag = 0;
        step = MATCH_START_PLAY;
        // printf(LOG_TAG);
#ifdef LOG_TEST
        printf("\nPLAY:match remote over......... \n");
#endif
        break;

    default:
        break;
    }
    printf("ReadmePlay ID: %d\n", f_asr_response);
    return 0;
}

int event_next_air_remote()
{
    int ret = 0;

    ret = match_get_next_remote(IR_DEV_AIR_COND);
    if (ret < 0)
    {
        printf("\nNo available data was detected!!!\n");
    }
    else
    {
        air_user_data_init();
        save_user_sta_data(&air_sta_data, sizeof(air_sta_data), IR_DEV_AIR_COND);
#ifdef LOG_TESTF
        printf("\nSuccessfully obtained the next set of remote control codes...\n");
#endif
    }
    return ret;
}

/**
 * @brief 打开空调
 * @return none
 */
int event_air_power_on()
{
    int ret = 0;
    unsigned char wind_direct_flag = 0;
    AIR_STA_T temp = air_sta_data;
    temp._power = 0;
    ret = air_power_switch(temp);
    if (ret < 0)
    {
        return ret;
    }
    temp._sync = 0;

    ret = remote_support_info(temp, &wind_direct_flag);
    if (ret < 0)
    {
        printf("\nOpen air data init...\n");
        air_user_data_init();
        temp = air_sta_data;
    }
    
    aos_msleep(50);
    
    ret = air_control(temp, wind_direct_flag);
    if (ret < 0)
    {
        return -2;
    }
    temp._sync = 1;
    air_sta_data = temp;
    return 0;
}

/**
 * @brief 关闭空调
 * @return none
 */
int event_air_power_off()
{
    int ret = 0;
    AIR_STA_T temp = air_sta_data;
    temp._power = 1;
    temp._sync = 1;
    ret = air_power_switch(temp);
    if (ret < 0)
    {
        return ret;
    }
    air_sta_data = temp;
    return 0;
}

/**
 * @brief 制冷模式
 * @return none
 */
int event_air_mode_cool()
{
    int ret = 0;
    unsigned char wind_direct_flag = 0;
    AIR_STA_T temp = air_sta_data;
    temp._mode = 0;
    temp._sync = 1;

    ret = remote_support_info(temp, &wind_direct_flag);
    if (ret == -2)
    {
        return -1;
    }

    ret = air_control(temp, wind_direct_flag);
    if (ret < 0)
    {
        return -2;
    }
    save_user_sta_data(&air_sta_data, sizeof(air_sta_data), IR_DEV_AIR_COND);
    air_sta_data = temp;
    return 0;
}

/**
 * @brief 加热模式
 * @return none
 */
int event_air_mode_hot()
{
    int ret = 0;
    unsigned char wind_direct_flag = 0;
    AIR_STA_T temp = air_sta_data;
    temp._mode = 1;
    temp._sync = 1;

    ret = remote_support_info(temp, &wind_direct_flag);
    if (ret == -2)
    {
        return -1;
    }

    ret = air_control(temp, wind_direct_flag);
    if (ret < 0)
    {
        return -2;
    }
    save_user_sta_data(&air_sta_data, sizeof(air_sta_data), IR_DEV_AIR_COND);
    air_sta_data = temp;
    return 0;
}

/**
 * @brief 自动模式
 * @return none
 */
int event_air_mode_auto()
{
    int ret = 0;
    unsigned char wind_direct_flag = 0;
    AIR_STA_T temp = air_sta_data;
    temp._mode = 2;
    temp._sync = 1;

    ret = remote_support_info(temp, &wind_direct_flag);
    if (ret == -2)
    {
        return -1;
    }

    ret = air_control(temp, wind_direct_flag);
    if (ret < 0)
    {
        return -2;
    }
    save_user_sta_data(&air_sta_data, sizeof(air_sta_data), IR_DEV_AIR_COND);
    air_sta_data = temp;
    return 0;
}

/**
 * @brief 送风模式
 * @return none
 */
int event_air_mode_wind()
{
    int ret = 0;
    unsigned char wind_direct_flag = 0;
    AIR_STA_T temp = air_sta_data;
    temp._mode = 3;
    temp._sync = 1;

    ret = remote_support_info(temp, &wind_direct_flag);
    if (ret == -2)
    {
        return -1;
    }

    ret = air_control(temp, wind_direct_flag);
    if (ret < 0)
    {
        return -2;
    }
    save_user_sta_data(&air_sta_data, sizeof(air_sta_data), IR_DEV_AIR_COND);
    air_sta_data = temp;
    return 0;
}

/**
 * @brief 除湿模式
 * @return none
 */
int event_air_mode_wetted()
{
    int ret = 0;
    unsigned char wind_direct_flag = 0;
    AIR_STA_T temp = air_sta_data;
    temp._mode = 4;
    temp._sync = 1;

    ret = remote_support_info(temp, &wind_direct_flag);
    if (ret == -2)
    {
        return -1;
    }

    ret = air_control(temp, wind_direct_flag);
    if (ret < 0)
    {
        return -2;
    }
    save_user_sta_data(&air_sta_data, sizeof(air_sta_data), IR_DEV_AIR_COND);
    air_sta_data = temp;
    return 0;
}

/**
 * @brief 空调温度设置
 * @param[in] {value}    温度[16-30]
 * @return 0: OK    1: out of range  -1: Can't adjust
 */
int event_air_temperature_set(unsigned char value)
{
    int ret = 0;
    unsigned char wind_direct_flag = 0;
    AIR_STA_T temp = air_sta_data;

    if (value >= 16 && value <= 30)
    {
        temp._temperature = value;
        temp._sync = 1;

        ret = remote_support_info(temp, &wind_direct_flag);
        if (ret == -3)
        {
            return -1;
        }

        ret = air_control(temp, wind_direct_flag);
        if (ret < 0)
        {
            return -2;
        }
        save_user_sta_data(&air_sta_data, sizeof(air_sta_data), IR_DEV_AIR_COND);
        air_sta_data = temp;
    }
    else
    {
        printf("\nTemperature out of range\n");
        ret = 1;
    }

    return ret;
}

/**
 * @brief 调高温度
 * @return 0: OK    1: max  -1: Can't adjust
 */
int event_air_temperature_increase()
{
    int ret = 0;
    unsigned char wind_direct_flag = 0;
    AIR_STA_T temp = air_sta_data;
    if (temp._temperature >= 32)
    {
        temp._temperature = 32;
        ret = 1;
    }
    else
    {
        temp._temperature++;
    }
    temp._sync = 1;

    ret = remote_support_info(temp, &wind_direct_flag);
    if (ret == -3)
    {
        return -1;
    }

    ret = air_control(temp, wind_direct_flag);
    if (ret < 0)
    {
        return -2;
    }
    save_user_sta_data(&air_sta_data, sizeof(air_sta_data), IR_DEV_AIR_COND);
    air_sta_data = temp;

    return ret;
}

/**
 * @brief 调低温度
 * @return 0: OK    1: min  -1: Can't adjust
 */
int event_air_temperature_reduce()
{
    int ret = 0;
    unsigned char wind_direct_flag = 0;
    AIR_STA_T temp = air_sta_data;
    if (temp._temperature <= 16)
    {
        temp._temperature = 16;
        ret = 1;
    }
    else
    {
        temp._temperature--;
    }
    temp._sync = 1;

    ret = remote_support_info(temp, &wind_direct_flag);
    if (ret == -3)
    {
        return -1;
    }

    ret = air_control(temp, wind_direct_flag);
    if (ret < 0)
    {
        return -2;
    }
    save_user_sta_data(&air_sta_data, sizeof(air_sta_data), IR_DEV_AIR_COND);
    air_sta_data = temp;

    return ret;
}

/**
 * @brief 自动风量
 * @return none
 */
int event_air_wind_speed_auto()
{
    int ret = 0;
    unsigned char wind_direct_flag = 0;
    AIR_STA_T temp = air_sta_data;
    temp._wind_speed = 0;
    temp._sync = 1;

    ret = remote_support_info(temp, &wind_direct_flag);
    if (ret == -4)
    {
        return -1;
    }

    ret = air_control(temp, wind_direct_flag);
    if (ret < 0)
    {
        return -2;
    }
    save_user_sta_data(&air_sta_data, sizeof(air_sta_data), IR_DEV_AIR_COND);
    air_sta_data = temp;

    return ret;
}

/**
 * @brief 最小风量
 * @return none
 */
int event_air_wind_speed_min()
{
    int ret = 0;
    unsigned char wind_direct_flag = 0;
    AIR_STA_T temp = air_sta_data;
    temp._wind_speed = 1;
    temp._sync = 1;

    ret = remote_support_info(temp, &wind_direct_flag);
    if (ret == -4)
    {
        return -1;
    }

    ret = air_control(temp, wind_direct_flag);
    if (ret < 0)
    {
        return ret;
    }
    save_user_sta_data(&air_sta_data, sizeof(air_sta_data), IR_DEV_AIR_COND);
    air_sta_data = temp;

    return ret;
}

/**
 * @brief 中等风量
 * @return none
 */
int event_air_wind_speed_mid()
{
    int ret = 0;
    unsigned char wind_direct_flag = 0;
    AIR_STA_T temp = air_sta_data;
    temp._wind_speed = 2;
    temp._sync = 1;

    ret = remote_support_info(temp, &wind_direct_flag);
    if (ret == -4)
    {
        return -1;
    }

    ret = air_control(temp, wind_direct_flag);
    if (ret < 0)
    {
        return ret;
    }
    save_user_sta_data(&air_sta_data, sizeof(air_sta_data), IR_DEV_AIR_COND);
    air_sta_data = temp;

    return ret;
}

/**
 * @brief 最大风量
 * @return none
 */
int event_air_wind_speed_max()
{
    int ret = 0;
    unsigned char wind_direct_flag = 0;
    AIR_STA_T temp = air_sta_data;
    temp._wind_speed = 3;
    temp._sync = 1;

    ret = remote_support_info(temp, &wind_direct_flag);
    if (ret == -4)
    {
        return -1;
    }

    ret = air_control(temp, wind_direct_flag);
    if (ret < 0)
    {
        return ret;
    }
    save_user_sta_data(&air_sta_data, sizeof(air_sta_data), IR_DEV_AIR_COND);
    air_sta_data = temp;

    return ret;
}

/**
 * @brief 上下扫风
 * @return none
 */
int event_air_mode_direction()
{
    int ret = 0;
    unsigned char wind_direct_flag = 0;
    AIR_STA_T temp = air_sta_data;
    temp._wind_direction = 0;
    temp._sync = 1;

    ret = remote_support_info(temp, &wind_direct_flag);
    if (ret == -1 || wind_direct_flag == 0)
    {
        return -1;
    }

    ret = air_direct_ctrl(temp, wind_direct_flag);
    if (ret < 0)
    {
        return -2;
    }
    save_user_sta_data(&air_sta_data, sizeof(air_sta_data), IR_DEV_AIR_COND);
    air_sta_data = temp;

    return ret;
}
/**
 * @brief 停止扫风
 * @return none
 */
int event_air_mode_stop_direction()
{
    int ret = 0;
    unsigned char wind_direct_flag = 0;
    AIR_STA_T temp = air_sta_data;
    temp._wind_direction = 1;
    temp._sync = 1;

    ret = remote_support_info(temp, &wind_direct_flag);
    if (ret == -1 || wind_direct_flag == 0)
    {
        return -1;
    }

    ret = air_direct_ctrl(temp, wind_direct_flag);
    if (ret < 0)
    {
        return -3;
    }
    save_user_sta_data(&air_sta_data, sizeof(air_sta_data), IR_DEV_AIR_COND);
    air_sta_data = temp;

    return ret;
}